<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>canvas - 截图</title>
    <link rel="stylesheet" href="https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/static/protocol/https/soutu/css/soutu.css">
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        html,body{
            height: 100%;
            width: 100%;
        }
        .box>p{
            margin-left: 40px;
        }
        .canvas{
            border: 1px solid #ccc;
            margin: 10px;
        }
        .select{
            display: flex;
        }
        label, .download, .revoke{
            display: inline-block;
            border: 1px solid #ccc;
            padding: 10px 15px;
            margin-right: 10px;
            border-radius: 20px;
            font-size: 14px;
            outline: none;
            background: white;
            cursor: pointer;
        }
        label:hover{
            background: #e2e2e2;
            color: rgb(63, 175, 219);
        }
        .download:hover{
            background: #e2e2e2;
            color: rgb(63, 175, 219);
        }
        .revoke:hover{
            background: #e2e2e2;
            color: rgb(63, 175, 219);
        }
        input[type='file']{
            display: none;
        }
        .download{
            display: none;
        }
        .revoke{
            display: none;
            padding: 10px 30px;
        }
    </style>
</head>
<body>
    <div class="box">
            提示:<p>选择图片后，在图片区域内连续点击两次以确定截图区域，截图选择成功后会出现区域框提示，<br/>
            撤销：撤销截图
            保存图片：下载截图图片
        </p>
        <canvas ref='canvas' class="canvas" width="0" height="0"></canvas>
        <div class="select">
            <label for="ci">选择图片</label>
            <input id="ci" type="file" @change='getImage'>
            <button @click='downLoad' class="download">保存图片</button>
            <button @click='revoke' class="revoke">撤销</button>
        </div>
        
    </div>
    <script src="./js/vue.js"></script>
    <script>
        let  image = new Image(),
             width = 0,
             height = 0,
             imageType = 'image/png',
             firstChange = true,
             rectColor = 'red',
             imgURL = '';
        //newImage:截图图片base64字符 oldImage:选择截图前的图片（最开始选择的图片） cutImage:截图区域内容
        let canvas,ctx,newImage,oldImage,cutImage;   
        let clone = [];

        let vm = new Vue({
            el:'.box',
            data:{
                clickNum: 0
            },
            mounted(){
                
            },
            methods:{
                //显示图片
                getImage(){
                    var _this = this;
                    var file = event.target.files;
                    _this.clickNum = 0;
                    if(file.length >0){
                        var URL = window.URL || window.webkitURL;
                        imgURL = URL.createObjectURL(file[0]);
                        image.src = imgURL;
                        image.onload = function(){
                            //获取图片宽高
                            height = this.height;
                            width = this.width;
                            
                            //设置canvas大小
                            _this.$refs.canvas.height = height;
                            _this.$refs.canvas.width = width;

                            canvas = document.querySelector('.canvas');
                            ctx = canvas.getContext('2d');
                            ctx.beginPath();
                            //绘制图片
                            ctx.drawImage(this,0, 0,width,height);
                            //记录此canvas内容
                            oldImage = ctx.getImageData(0,0,width,height);
                            if(firstChange){
                                //图片显示后，监控截图
                                _this.listerner();  
                            }
                            
                            firstChange = false;
                        }
                    }
                },

                //启动监控 - 点击事件 - 是否选择截图区间
                listerner(){
                    var _this = this;
                    document.querySelector('body').addEventListener('click',function(event){
                        if(event.path[0].className.indexOf('canvas') != -1){
                            _this.clickNum = _this.clickNum + 1;
                            if(_this.clickNum == 1){
                                clone.push({x:event.layerX,y:event.layerY});
                            }else if(_this.clickNum == 2){
                                clone.push({xx:event.layerX,yy:event.layerY})
                                if(clone[0].x == clone[1].xx || clone[0].y == clone[1].yy){
                                    clone = [];
                                }else{
                                    _this.drawRect();
                                }
                            }
                            
                        }else if(_this.clickNum == 1){
                            clone = [];
                            _this.clickNum = 0;
                        }
                    })
                },

                //绘制截图矩阵
                drawRect(){
                    //选择截图区域
                    if(clone[0].x > clone[1].xx){
                        if(clone[0].y < clone[1].yy){
                            //第一点为右上角
                            //绘制截图框
                            ctx.beginPath();
                            ctx.strokeStyle = rectColor;
                            //截图宽度
                            var w = clone[0].x - clone[1].xx;
                            //截图高度
                            var h = clone[1].yy - clone[0].y;
                            //获取截图区域内容
                            cutImage = ctx.getImageData(clone[1].xx,clone[0].y,w,h);
                            //绘制截图框
                            ctx.strokeRect(clone[1].xx,clone[0].y,w,h);
                            //将截图内容转化base64
                            newImage = this.createNewCanvas(cutImage,w,h);
                            

                            //显示保存图片、撤回按钮
                            document.querySelector('.download').style.display = 'block';
                            document.querySelector('.revoke').style.display = 'block';
                            
                        }else{
                            //第一点为右下角
                            //绘制截图框
                            ctx.beginPath();
                            ctx.strokeStyle = rectColor;
                            //截图宽度
                            var w = clone[0].x - clone[1].xx;
                            //截图高度
                            var h = clone[0].y - clone[1].yy;
                            //获取截图区域内容
                            cutImage = ctx.getImageData(clone[1].xx,clone[1].yy,w,h);
                            //绘制截图框
                            ctx.strokeRect(clone[1].xx,clone[1].yy,w,h);
                            //将截图内容转化base64
                            newImage = this.createNewCanvas(cutImage,w,h);
                            

                            //显示保存图片、撤回按钮
                            document.querySelector('.download').style.display = 'block';
                            document.querySelector('.revoke').style.display = 'block';
                        }
                    }else{
                        if(clone[0].y < clone[1].yy){
                            //第一点为左上角
                            //绘制截图框
                            ctx.beginPath();
                            ctx.strokeStyle = rectColor;
                            //截图宽度
                            var w = clone[1].xx - clone[0].x;
                            //截图高度
                            var h = clone[1].yy - clone[0].y;
                            //获取截图区域内容
                            cutImage = ctx.getImageData(clone[0].x,clone[0].y,w,h);
                            //绘制截图框
                            ctx.strokeRect(clone[0].x,clone[0].y,w,h);
                            //将截图内容转化base64
                            newImage = this.createNewCanvas(cutImage,w,h);
                            

                            //显示保存图片、撤回按钮
                            document.querySelector('.download').style.display = 'block';
                            document.querySelector('.revoke').style.display = 'block';
                            
                        }else{
                            //第一点为左下角
                            //绘制截图框
                            ctx.beginPath();
                            ctx.strokeStyle = rectColor;
                            //截图宽度
                            var w = clone[1].xx - clone[0].x;
                            //截图高度
                            var h = clone[0].y - clone[1].yy;
                            //获取截图区域内容
                            cutImage = ctx.getImageData(clone[0].x,clone[1].yy,w,h);
                            //绘制截图框
                            ctx.strokeRect(clone[0].x,clone[1].yy,w,h);
                            //将截图内容转化base64
                            newImage = this.createNewCanvas(cutImage,w,h);
                            

                            //显示保存图片、撤回按钮
                            document.querySelector('.download').style.display = 'block';
                            document.querySelector('.revoke').style.display = 'block';
                            
                        }
                    }
                },

                //撤销截图
                revoke(){
                    ctx.putImageData(oldImage,0,0);
                    clone = [];
                    this.clickNum = 0;
                    document.querySelector('.download').style.display = 'none';
                },

                //保存图片
                downLoad(){
                    var da = document.createElement('a');
                    var date = new Date();
                    var imageName = prompt('存储图片名称？',date.getTime());
                    if(imageName != null){
                        da.download = imageName;
                        da.href = newImage;
                        document.body.appendChild(da);
                        da.click();
                        da.remove();
                        document.querySelector('.download').style.display = 'none';
                    }
                    
                },

                //创建新的空白canvas画布并将截图渲染
                createNewCanvas(content,width,height){
                    var nCanvas = document.createElement('canvas');
                    var nCtx = nCanvas.getContext('2d');
                    nCanvas.width = width;
                    nCanvas.height = height;
                    nCtx.putImageData(content,0,0);
                    //显示截图
                    // document.querySelector('body').append(nCanvas); 
                    return nCanvas.toDataURL(imageType);
                }
            },
        })
        
        
    </script>
</body>
</html>